package com.JFapp.service.impl;

import com.JFapp.constants.SystemConstants;
import com.JFapp.domain.dto.EmpowerDto;
import com.JFapp.domain.dto.RoleMenuIdsDto;
import com.JFapp.domain.entity.ResponseResult;
import com.JFapp.domain.entity.Role;
import com.JFapp.domain.entity.User;
import com.JFapp.domain.vo.PageVo;
import com.JFapp.domain.vo.RoleVo;
import com.JFapp.eumns.AppHttpCodeEnum;
import com.JFapp.exception.SystemException;
import com.JFapp.mapper.RoleMapper;
import com.JFapp.service.RoleService;
import com.JFapp.service.UploadService;
import com.JFapp.service.UserService;
import com.JFapp.utils.BeanCopyUtils;
import com.JFapp.utils.SecurityUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.internal.LinkedHashTreeMap;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 计服角色表(Role)表服务实现类
 *
 * @author makejava
 * @since 2023-12-06 20:50:51
 */
@Service("roleService")
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Override
    @Transactional(rollbackFor = SystemException.class)
    public ResponseResult addRole(RoleMenuIdsDto roleMenuIdsDto) {
        //判断管理员身份
        if(!SecurityUtils.isAdmin()){
            throw new SystemException(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
            Role role = BeanCopyUtils.copyBean(roleMenuIdsDto, Role.class);
            role.setCreateBy(SecurityUtils.getUserId());
            role.setCreateTime(new Date());
            save(role);
            List<Long> menuIds = roleMenuIdsDto.getMenuIds();
            if (menuIds!=null&&menuIds.size()>0){
                baseMapper.insertRoleAndMenu(menuIds,role.getId());
            }else {
                throw new SystemException(AppHttpCodeEnum.ADD_ROLE_ERROR);
            }
        return ResponseResult.okResult();
    }

    @Override
    @ApiOperation("赋予角色")
    public ResponseResult empower(List<User> users, Long rid) {
        if(!SecurityUtils.isAdmin()){
            throw new SystemException(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        if (rid!=null&&baseMapper.selectById(rid)!=null){
            List<Long> uid = users.stream().map(User::getId).collect(Collectors.toList());
            getBaseMapper().insertRole(uid,rid);
            return ResponseResult.okResult();
        }else {
            throw new SystemException(AppHttpCodeEnum.NOT_FIND_ROLE);
        }
    }
    @Autowired
    private UploadService uploadService;

    @Autowired
    private UserService userService;
    @Override
    public ResponseResult empower(MultipartFile file) throws IOException {

        List<EmpowerDto> empowerDtos = uploadService.uploadExcel(file);
        List<String> userName = empowerDtos.stream().map(empowerDto -> empowerDto.getUserName()).collect(Collectors.toList());
        List<Long> userId = userService.selectIDs(userName);
        baseMapper.deleteRoleAndUser(userId);
        Map<Long,Long> empowers= empowerDtos.stream()
                .collect(Collectors.toMap(e->userId.get(empowerDtos.indexOf(e)),e->e.getRoleId(),(u,v)->u, LinkedHashTreeMap::new));
        baseMapper.empower(empowers);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult selectRoleById(Long roleId) {
        Role role = baseMapper.selectById(roleId);
        return ResponseResult.okResult(role);
    }

    @Override
    public ResponseResult changeRole(RoleMenuIdsDto roleMenuIdsDto) {
        Role role = BeanCopyUtils.copyBean(roleMenuIdsDto, Role.class);
        updateById(role);
        List<Long> menuIds = roleMenuIdsDto.getMenuIds();
        if (menuIds!=null&&menuIds.size()>0){
            baseMapper.deleteRoleAndMenu(role.getId());
            baseMapper.insertRoleAndMenu(menuIds,role.getId());
        }
        return ResponseResult.okResult();
    }

    @Override
    public List<Long> selectRoleIdByUserId(Long userId) {
        return baseMapper.selectRoleIdByUserId(userId);
    }

    @Override
    public ResponseResult selectAllRole() {
        LambdaQueryWrapper<Role> queryWrapper= new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Role> wrapper = queryWrapper.select().eq(Role::getStatus, SystemConstants.STATUS_NORMAL);
        List<Role> roles = list(wrapper);
        return ResponseResult.okResult(roles);
    }

    @Override
    public void updateRoleAndUser(Long id,List<Long> roleIds) {
        baseMapper.deleteRoleAndUser1(id);
        baseMapper.insertRoleAndUser(id,roleIds);
    }

    @Override
    @ApiOperation("更改角色状态")
    public ResponseResult changeStatus(Long roleId,String status) {
        if(!SecurityUtils.isAdmin()){
            throw new SystemException(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        if (roleId!=null&&baseMapper.selectById(roleId)!=null){
        LambdaUpdateWrapper<Role> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Role::getStatus,status).eq(Role::getId,roleId);
        return ResponseResult.okResult();
        }else {
            throw new SystemException(AppHttpCodeEnum.NOT_FIND_ROLE);
        }
    }

    @Override
    @ApiOperation("查询角色")
    public ResponseResult selectRole(Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByAsc(Role::getRoleSort);
        Page<Role> rolePage= new Page<>(pageNum,pageSize);
        Page<Role> page = page(rolePage, wrapper);
        List<Role> records = rolePage.getRecords();
        List<RoleVo> roleVos = BeanCopyUtils.copyBeanList(records, RoleVo.class);

        PageVo pageVo = new PageVo(roleVos,page.getTotal());

        return ResponseResult.okResult(pageVo);
    }

    @Override
    @ApiOperation("查询用户所拥有角色")
    public List<String> selectRoleKeyListByUserId(Long id) {
        //判断是否为管理员，如果是返回集合中只需要有admin
        if(id==1l){
            List<String> roleKeys = new ArrayList<>();
            roleKeys.add("admin");
            return  roleKeys;
        }
        //否则查询用户所拥有的角色信息
        return getBaseMapper().selectRoleKeysById(id);
    }


}
